package com.weimob.mcloud.wechatwork.customer.export;

import com.weimob.mcloud.wechatwork.customer.service.user.module.bo.dynamic.DynamicThreadPollBo;
import com.weimob.mcloud.wechatwork.customer.service.user.module.req.dynamic.DynamicThreadPollReq;
import com.weimob.mcloud.wechatwork.customer.service.user.service.DynamicThreadPoolService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author wei.zhai
 * @desc 动态线程池相关
 * @date 2023/01/11
 */
@Service
@Slf4j
public class DynamicThreadPoolServiceImpl implements DynamicThreadPoolService {

    //spring map回自动注入已经被spring接管的value bean
    @Autowired
    private Map<String, ThreadPoolTaskExecutor> threadPoolTaskExecutorMap = new HashMap<>();


    /**
     * 动态设置指定线程池核心线程数
     *
     * @param dynamicThreadPollReq 线程池参数实体
     * @return
     */
    @Override
    public DynamicThreadPollBo dynamicCorePoolSize(DynamicThreadPollReq dynamicThreadPollReq) {
        Integer corePoolSize = dynamicThreadPollReq.getCorePoolSize();

        ThreadPoolTaskExecutor threadPoolTaskExecutor = threadPoolTaskExecutorMap.get(dynamicThreadPollReq.getThreadPoolName());

        if(Objects.isNull(threadPoolTaskExecutor)) return null;

        if(Objects.nonNull(corePoolSize)) {
            threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
        }

        if(Objects.nonNull(dynamicThreadPollReq.getShowThreadPoolMetadata()) && dynamicThreadPollReq.getShowThreadPoolMetadata()) {
            return getThreadPoolDesc(dynamicThreadPollReq);
        }
        return null;
    }


    /**
     * 动态设置指定线程池最大线程数
     *
     * @param dynamicThreadPollReq 线程池参数实体
     * @return
     */
    @Override
    public DynamicThreadPollBo dynamicMaximumPoolSize(DynamicThreadPollReq dynamicThreadPollReq) {
        Integer maxPoolSize = dynamicThreadPollReq.getMaxPoolSize();

        ThreadPoolTaskExecutor threadPoolTaskExecutor = threadPoolTaskExecutorMap.get(dynamicThreadPollReq.getThreadPoolName());

        if(Objects.isNull(threadPoolTaskExecutor)) return null;

        if(Objects.nonNull(maxPoolSize)) {
            threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
        }

        if(Objects.nonNull(dynamicThreadPollReq.getShowThreadPoolMetadata()) && dynamicThreadPollReq.getShowThreadPoolMetadata()) {
            return getThreadPoolDesc(dynamicThreadPollReq);
        }
        return null;
    }


   @Override
    public DynamicThreadPollBo dynamicCoreAndMaximumPoolSize(DynamicThreadPollReq dynamicThreadPollReq) {
        dynamicThreadPollReq.setShowThreadPoolMetadata(Boolean.FALSE);
        dynamicCorePoolSize(dynamicThreadPollReq);
        dynamicMaximumPoolSize(dynamicThreadPollReq);
        return getThreadPoolDesc(dynamicThreadPollReq);
    }

    /**
     * 动态实时查询指定线程池参数，每一个参数查询都会lock一次，请谨慎调用，避免多次重复调用
     *
     * @param dynamicThreadPollReq 线程池参数实体
     * @return
     */
    @Override
    public DynamicThreadPollBo getThreadPoolDesc(DynamicThreadPollReq dynamicThreadPollReq) {

        DynamicThreadPollBo dynamicThreadPoll = new DynamicThreadPollBo();

        ThreadPoolTaskExecutor threadPoolTaskExecutor = threadPoolTaskExecutorMap.get(dynamicThreadPollReq.getThreadPoolName());

        if(Objects.isNull(threadPoolTaskExecutor)) return null;

        //当前排队线程数
        int queueSize = threadPoolTaskExecutor.getThreadPoolExecutor().getQueue().size();
        dynamicThreadPoll.setQueueSize(queueSize);

        //当前活动线程数
        int activeCount = threadPoolTaskExecutor.getActiveCount();
        dynamicThreadPoll.setActiveCount(activeCount);

        //执行完成线程数
        long completeTaskCount = threadPoolTaskExecutor.getThreadPoolExecutor().getCompletedTaskCount();
        dynamicThreadPoll.setCompleteTaskCount(completeTaskCount);

        //总线程数
        long taskCount = threadPoolTaskExecutor.getThreadPoolExecutor().getTaskCount();
        dynamicThreadPoll.setTaskCount(taskCount);

        //最大线程数
        int maximumPoolSize = threadPoolTaskExecutor.getThreadPoolExecutor().getMaximumPoolSize();
        dynamicThreadPoll.setMaxPoolSize(maximumPoolSize);

        //核心线程数
        int corePoolSize = threadPoolTaskExecutor.getThreadPoolExecutor().getCorePoolSize();
        dynamicThreadPoll.setCorePoolSize(corePoolSize);

        //返回池中的当前线程数。
        int poolSize = threadPoolTaskExecutor.getThreadPoolExecutor().getPoolSize();
        dynamicThreadPoll.setPollSize(poolSize);

        //池中曾经最大线程数
        int largestPoolSize = threadPoolTaskExecutor.getThreadPoolExecutor().getLargestPoolSize();
        dynamicThreadPoll.setLargestPoolSize(largestPoolSize);

        return dynamicThreadPoll;
    }
}
